package com.briup.smartcity_group7.log;
import com.briup.smartcity_group7.dao.ext.BaseUserExtMapper;
import com.briup.smartcity_group7.service.IBaseLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Aspect   //切面类
@Component
public class LogAspect {
    @Autowired //对象依赖关系切面类对象中需要ioc容器提供映射器对象
    private IBaseLogService logService;
    @Autowired
    private BaseUserExtMapper userExtMapper;//查询真实用户姓名


    //定义切入点：选择什么方法添加的日志功能
    @Pointcut("execution(* com.briup.smartcity_group7.service.*.*(..) )")
    public void logPointCut(){
        //规则通过表达式表示
    }

    //通过指定不同类型的通知实现添加日志的操作 ：前置 后置 最终 环绕 异常


    //方式1：每次方法开始执行前进行记录,选择前置通知 75 85+  创新 90+
    @Before("logPointCut()")
    public void beforeAdvice(){
        /*
            记录日志信息，并保存在数据库base_log表中
            请求头(token):  username---->realname(真实姓名)
            请求对象：requetMethod(请求方法) uri(请求路径)
            log_time： new Date();
            将日志信息保存数据库？Mapper进行插入操作
         */

        //如何获取请求对象(请求信息)  拦截器(userInfo)->web(请求对象)->aop->service(userInfo)->dao
        log.info("开始记录日志信息:"+Thread.currentThread().getName());
        //通过请求对象上下文持有者类可以获取请求对象
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        log.info("method："+request.getMethod());
        log.info("uri："+request.getRequestURI());
        log.info("token:"+request.getHeader("Authorization"));

        //补充：通过解析jwt字符串 获取用户登录名username,realName(可以从userInfo Map集合,使用Mapper对象查询)

        //最终执行代码：logService.addBaseLog(....);
    }


    //补充2（扩展）：方式2：每次方法执行结束后记录, 选择最终通知 环绕通知


    /*
        补充3（扩展）： 当用户第一次登录系统时，他不提供token字符串,
        我们系统还需要记录用户的登录日志。如何实现该功能？
     */
}